package org.jeecg.modules.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.BeanPlusUtil;
import org.jeecg.modules.inventory.entity.BussInventory;
import org.jeecg.modules.inventory.entity.BussInventoryDetails;
import org.jeecg.modules.inventory.entity.BussInventoryInoutDetails;
import org.jeecg.modules.inventory.entity.BussInventoryPurchaseOrder;
import org.jeecg.modules.inventory.mapper.BussInventoryDetailsMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryInoutDetailsMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryMapper;
import org.jeecg.modules.inventory.mapper.BussInventoryPurchaseOrderMapper;
import org.jeecg.modules.procurement.entity.BussMaterialProcurement;
import org.jeecg.modules.procurement.entity.BussMaterialProcurementDetail;
import org.jeecg.modules.procurement.mapper.BussMaterialProcurementDetailMapper;
import org.jeecg.modules.procurement.mapper.BussMaterialProcurementMapper;
import org.jeecg.modules.storage.entity.*;
import org.jeecg.modules.storage.mapper.*;
import org.jeecg.modules.storage.service.IBussStorageService;
import org.jeecg.modules.storage.vo.BussStorageDetailVo;
import org.jeecg.modules.storage.vo.BussStoragePage;
import org.jeecg.modules.storage.vo.StoragePage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @Description: 入库单
 * @Author: jeecg-boot
 * @Date:   2024-06-20
 * @Version: V1.0
 */
@Service
public class BussStorageServiceImpl extends ServiceImpl<BussStorageMapper, BussStorage> implements IBussStorageService {

	@Autowired
	private BussStorageMapper bussStorageMapper;
	@Autowired
	private BussStorageDetailMapper bussStorageDetailMapper;
	@Autowired
	private BussInventoryMapper bussInventoryMapper;
	@Autowired
	private BussInventoryDetailsMapper bussInventoryDetailsMapper;
	@Autowired
	private BussInventoryInoutDetailsMapper bussInventoryInoutDetailsMapper;
	@Autowired
	private BussMaterialProcurementDetailMapper bussMaterialProcurementDetailMapper;
	@Autowired
	private BussStorageNoticeMaterialMapper bussStorageNoticeMaterialMapper;
	@Autowired
	private BussInventoryPurchaseOrderMapper bussInventoryPurchaseOrderMapper;
	@Autowired
	private BussMaterialProcurementMapper bussMaterialProcurementMapper;

	@Autowired
	private BussStorageNoticeMapper bussStorageNoticeMapper;

	@Autowired
	private BussStorageCarinfoMapper bussStorageCarinfoMapper;
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(BussStoragePage storagePage) {
		BussStorage bussStorage = BeanPlusUtil.toBean(storagePage, BussStorage.class);
		List<BussStorageDetail> bussStorageDetailList = storagePage.getBussStorageDetailList();
		List<BussStorageCarinfo> bussStorageCarList = storagePage.getBussStorageCarList();
		bussStorageMapper.insert(bussStorage);
		if(!CollectionUtils.isEmpty(bussStorageDetailList)) {
			for(BussStorageDetail entity:bussStorageDetailList) {
				//外键设置
				entity.setStorageId(bussStorage.getId());
				bussStorageDetailMapper.insert(entity);
				this.updateNoticeMaterial(entity);
				this.updateNotice(entity);
			}
		}
		if(!CollectionUtils.isEmpty(bussStorageCarList)){
			for (BussStorageCarinfo bussStorageCarinfo : bussStorageCarList) {
				bussStorageCarinfo.setStorageId(bussStorage.getId());
				bussStorageCarinfoMapper.insert(bussStorageCarinfo);
			}
		}
//		if(bussStorage.getNoticeId() != null){
//			bussStorageNoticeMapper.update(null,new LambdaUpdateWrapper<BussStorageNotice>()
//					.eq(BussStorageNotice::getId, bussStorage.getNoticeId())
//					.set(BussStorageNotice::getStatus,2));
//		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(BussStoragePage bussStoragePage) {
		BussStorage bussStorage = BeanPlusUtil.toBean(bussStoragePage, BussStorage.class);
		List<BussStorageDetail> bussStorageDetailList = bussStoragePage.getBussStorageDetailList();
		List<BussStorageCarinfo> bussStorageCarList = bussStoragePage.getBussStorageCarList();

		bussStorageMapper.updateById(bussStorage);
		this.updateNoticeMaterial(bussStorage.getId());
		//1.先删除子表数据
		bussStorageDetailMapper.deleteByMainId(bussStorage.getId());
		bussStorageCarinfoMapper.deleteByMainId(bussStorage.getId());
		//2.子表数据重新插入
		if(!CollectionUtils.isEmpty(bussStorageDetailList)) {
			for(BussStorageDetail entity:bussStorageDetailList) {
				//外键设置
				entity.setStorageId(bussStorage.getId());
				bussStorageDetailMapper.insert(entity);
				this.updateNoticeMaterial(entity);
				this.updateNotice(entity);
			}
		}
		if(!CollectionUtils.isEmpty(bussStorageCarList)){
			for (BussStorageCarinfo bussStorageCarinfo : bussStorageCarList) {
				bussStorageCarinfo.setStorageId(bussStorage.getId());
				bussStorageCarinfoMapper.insert(bussStorageCarinfo);
			}
		}

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
//		bussStorageDetailMapper.deleteByMainId(id);
//		bussStorageMapper.deleteById(id);
		this.deleteData(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
//			bussStorageDetailMapper.deleteByMainId(id.toString());
//			bussStorageMapper.deleteById(id);
			this.deleteData(id);
		}
	}

	/**
	 * 删除时修改入库通知单状态
	 * @param id
	 */
	private void deleteData(Serializable id){
		BussStorageDetail bussStorageDetail = bussStorageDetailMapper.selectById(id);
		bussStorageDetailMapper.deleteById(id);
		Long aLong = bussStorageDetailMapper.selectCount(new LambdaQueryWrapper<BussStorageDetail>().eq(BussStorageDetail::getStorageId, bussStorageDetail.getStorageId()));
		if(aLong == 0){
			bussStorageMapper.deleteById(bussStorageDetail.getStorageId());
		}
		if(bussStorageDetail.getNoticeDetailId() != null){
			this.updateNoticeStatus(bussStorageDetail.getStorageId());
		}
	}


	@Override
	public IPage<StoragePage> pagelist(Page<StoragePage> page, QueryWrapper<StoragePage> wrapper) {
		return bussStorageMapper.pagelist(page,wrapper);
	}

	@Override
	public IPage<StoragePage> queryList(Page<StoragePage> page, QueryWrapper<StoragePage> wrapper) {
		return bussStorageMapper.queryList(page,wrapper);
	}

	/**
	 * 删除时修改通知单状态
	 * @param storageId
	 */
	private void updateNoticeMaterial(String storageId){
		List<BussStorageDetailVo> bussStorageDetailVos = bussStorageDetailMapper.selectByMainId(storageId);
		List<BussStorageDetail> bussStorageDetails = BeanPlusUtil.toBeanList(bussStorageDetailVos, BussStorageDetail.class);
		for (BussStorageDetail bussStorageDetail : bussStorageDetails) {
			bussStorageNoticeMaterialMapper.update(null, new LambdaUpdateWrapper<BussStorageNoticeMaterial>()
					.eq(BussStorageNoticeMaterial::getId, bussStorageDetail.getNoticeDetailId())
					.set(BussStorageNoticeMaterial::getStatus, 2));

		}
	}

	/**
	 * 删除时修改状态
	 * @param storageId
	 */
	private void updateNoticeStatus(String storageId){
		List<BussStorageDetail> bussStorageDetails = bussStorageDetailMapper.selectList(new LambdaQueryWrapper<BussStorageDetail>().eq(BussStorageDetail::getStorageId, storageId));
		for (BussStorageDetail bussStorageDetail : bussStorageDetails) {
			bussStorageNoticeMapper.update(null, new LambdaUpdateWrapper<BussStorageNotice>().eq(BussStorageNotice::getId, bussStorageDetail.getNoticeDetailId())
					.set(BussStorageNotice::getStatus, 2));
		}
	}


	/**
	 * 修改入库通知单明细状态
	 * @param entity
	 */
	private void updateNoticeMaterial(BussStorageDetail entity){
		if(entity.getNoticeDetailId() == null){
			return;
		}
		BussStorageNoticeMaterial bussStorageNoticeMaterial = bussStorageNoticeMaterialMapper.selectById(entity.getNoticeDetailId());
		if(bussStorageNoticeMaterial == null){
			return;
		}
		List<BussStorageDetail> bussStorageDetails = bussStorageDetailMapper.selectList(new LambdaQueryWrapper<BussStorageDetail>().eq(BussStorageDetail::getNoticeDetailId, entity.getNoticeDetailId()));
		if(CollectionUtils.isEmpty(bussStorageDetails)){
			bussStorageNoticeMaterial.setStatus(0);
			bussStorageNoticeMaterialMapper.updateById(bussStorageNoticeMaterial);
			return;
		}
		BigDecimal reduce = bussStorageDetails.stream().map(item -> Optional.ofNullable(item.getNum()).orElse(BigDecimal.ZERO))
				.reduce(BigDecimal.ZERO, BigDecimal::add);
		if(  reduce.compareTo(entity.getNum()) == 0 ){
			bussStorageNoticeMaterial.setStatus(1);
		}else if( reduce.compareTo(entity.getNum()) > 0 ){
			bussStorageNoticeMaterial.setStatus(2);
		}else if( reduce.compareTo(entity.getNum()) < 0 ){
			throw new RuntimeException("不能大于入库通知单数量");
		}
		bussStorageNoticeMaterialMapper.updateById(bussStorageNoticeMaterial);
	}

	/**
	 * 修改入库通知单状态
	 */
	private void updateNotice(BussStorageDetail entity){
		if(entity.getNoticeDetailId() ==  null){
			return;
		}
		BussStorageNoticeMaterial bussStorageNoticeMaterial = bussStorageNoticeMaterialMapper.selectById(entity.getNoticeDetailId());
		List<BussStorageNoticeMaterial> bussStorageNoticeMaterials = bussStorageNoticeMaterialMapper.selectList(new LambdaQueryWrapper<BussStorageNoticeMaterial>()
				.eq(BussStorageNoticeMaterial::getNoticeId, bussStorageNoticeMaterial.getNoticeId()));
		long count = bussStorageNoticeMaterials.stream().filter(item -> !item.getStatus().equals(1)).count();
		if(count == 0){
			BussStorageNotice bussStorageNotice = bussStorageNoticeMapper.selectById(bussStorageNoticeMaterial.getNoticeId());
			bussStorageNotice.setStatus("4");
			bussStorageNoticeMapper.updateById(bussStorageNotice);
		}
	}

	/**
	 *
	 * 入库单更新库存跟明细
	 *
	 * @param bussStorage
	 * @param bussStorageDetailList
	 */



}
